#include "halCallBack.h"
#include "ctrl.hpp"
#include "drv_schedule.h"
#include "drv_shell.h"
#include "up_data_format.hpp"
#include "usart.h"
#include <cstdio>
#include "drv_shell.h"


bool adc_restart_flag = false;// 为true后，在之后的一个周期重启开始启动传输循环
void stop_adc_read() {
    for (auto &i: brd.adc) {
        i.StopRead();
    }
    adc_restart_flag = true;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    if (htim == brd.htim_pit) // AD采集定时器
    {
        static uint32_t counter = 0;
        counter++;
        counter %= 666;//这里不能和控制周期一致
        updata_fifo.m_buffer[updata_fifo.m_in].pkg_idx = counter;

        if (__HAL_TIM_GET_COUNTER(brd.htim_counter) > (1U << 30)) {
            __HAL_TIM_GET_COUNTER(brd.htim_counter) = 0;
        }
        brd.htim_counter_data[0] = __HAL_TIM_GET_COUNTER(brd.htim_counter);

        //开始采样

//        {//for debug......
//            brd.adc[0].m_convsta = 0;
//            brd.adc[0].m_convsta = 1;
//        }
        // 采集周期，这里只触发采集，其余在其他中断处理
        if (adc_restart_flag) {
            adc_restart_flag = false;
            for (auto &i: brd.adc) {
                i.StopRead();
            }
            brd.flag_adc_busy_mask = 0;
            brd.flag_spi_busy = false;
        }

        for (auto &i: brd.adc) {
            i.m_convsta = 0;
        }
        for (auto &i: brd.adc) {
            i.m_convsta = 1;
        }


    }
}
void select_adc_start_read() {
    if (brd.flag_spi_busy)
        return;
    for (int i = 0; i < brd.adc.size(); i++) {
        auto &adc = brd.adc[i];
        if ((brd.flag_adc_busy_mask & (1U << i)) != 0) {
            brd.flag_spi_busy = true;
            adc.StartOfRead();
            return;
        }
    }
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    if (adc_restart_flag)
        return;
    for (int i = 0; i < brd.adc.size(); i++) {
        auto &adc = brd.adc[i];
        if (adc.IsOpen && GPIO_Pin == adc.m_busy.m_GPIO_Pin) {
            if ((brd.flag_adc_busy_mask & (1U << i)) != 0) {
                printf("%d跳\n", i);
                stop_adc_read();
            }
            brd.flag_adc_busy_mask |= 1U << i;
            brd.led[i] = 1;
            brd.htim_counter_data[1] = __HAL_TIM_GET_COUNTER(brd.htim_counter);//开始传输
            break;
        }
    }
    ScheduleActive(select_adc_start_read);
}
//此函数已经是在PendCV中调用的了
void ctrl_process() {
    brd.htim_counter_data[2] = __HAL_TIM_GET_COUNTER(brd.htim_counter);//传输完成 开始控制
    //准备下一次的缓存
    updata_fifo.m_in = (++updata_fifo.m_in) & updata_fifo.m_size_mask;
    for (int i = 0; i < brd.adc.size(); ++i) {
        brd.adc[i].PrepareXferBuff(updata_fifo.m_buffer[updata_fifo.m_in].adc_buf[i]);
        brd.adc[i].SetUsingData(updata_fifo.m_buffer[updata_fifo.m_using].adc_buf[i]);
    }
    brd.dac.SetBuf(updata_fifo.m_buffer[updata_fifo.m_using].dac_buf[0]);
    ctrl.Process();
    updata_fifo.m_using = (++updata_fifo.m_using) & updata_fifo.m_size_mask;
    brd.htim_counter_data[7] = __HAL_TIM_GET_COUNTER(brd.htim_counter);//传输完成 开始控制
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {
    for (int i = 0; i < brd.adc.size(); ++i) {
        auto &adc = brd.adc[i];
        if (hspi == adc.m_spi) {
            adc.EndOfRead();              // 读取完成 关闭片选
            brd.flag_adc_busy_mask &= ~(1U << i); // 相应位置清零
            brd.led[i] = 0;                    // 关灯
            if (brd.flag_adc_busy_mask == 0) {
                ScheduleActive(ctrl_process);// 唤起控制服务程序
            };
            break;
        }
    }
    brd.flag_spi_busy = false;
    ScheduleActive(select_adc_start_read);
}

void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) {
    stop_adc_read();
    printf("SPI_HandleTypeDef 0x%lx 出错 code=%lu\r\n", (uint32_t) hspi, hspi->ErrorCode);
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
    if (huart == &huart3) {
        shell_tx_service();
    }
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
    printf("UART_HandleTypeDef 0x%lx 出错 code=%lu\r\n", (uint32_t) huart, huart->ErrorCode);
}